﻿#region Copyright Notice
// 
// 
// Copyright (c) 2009-2010 Anindya Chatterjee
// 
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// 
//     http://www.apache.org/licenses/LICENSE-2.0
// 
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// 
// 
// 
#endregion
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Net;
using System.Windows.Forms;
using GCodeIssueTracker;
using GCodeIssueTracker.Comments;
using GCore;

namespace Demo
{
    public partial class Window : Form
    {
        private const string OldVersion = "1.1.0.0";
        private const string UpdateUrl = "http://google-code-issue-tracker.googlecode.com/files/version.txt";
        private string _downloadString;
        private string _gPassword;
        private string _gUserId;
        private string _newVersion;
        private string _projectName;
        private WebProxy _proxy;
        private ProjectHostingService _service;
        private string _setupFileName;
        private bool _updateAvailable;

        public Window()
        {
            InitializeComponent();
        }

        private void proxyButton_Click(object sender, EventArgs e)
        {
            try
            {
                _proxy = new WebProxy(proxyHostTextBox.Text, int.Parse(proxyPortTextBox.Text))
                             {
                                 Credentials = new NetworkCredential
                                                   {
                                                       UserName = proxyUsernameTextBox.Text,
                                                       Password = proxyPassTextBox.Text
                                                   }
                             };
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void projNameTextBox_TextChanged(object sender, EventArgs e)
        {
            _projectName = projNameTextBox.Text;
        }

        private void gAccIdTextBox_TextChanged(object sender, EventArgs e)
        {
            _gUserId = gAccIdTextBox.Text;
        }

        private void gPassTextBox_TextChanged(object sender, EventArgs e)
        {
            _gPassword = gPassTextBox.Text;
        }

        private void getIssueButton_Click(object sender, EventArgs e)
        {
            try
            {
                if (_service == null)
                {
                    _service = new ProjectHostingService(_projectName, _gUserId, _gPassword);
                    if (_proxy != null)
                        _service.ProxySettings = _proxy;
                }

                _service.GetAllIssuesCompleted += ServiceGetAllIssuesCompleted;
                _service.GetAllIssuesAsync(new object());
                ButtonEnableState(false);
                statusLabel.Text = "Fetching Issues ....";
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void ServiceGetAllIssuesCompleted(object sender, GetAllFeedCompletedEventArgs<IssuesFeed, IssuesEntry> e)
        {
            statusLabel.Text = "";
            ButtonEnableState(true);

            issueListBox.Items.Clear();
            IssuesFeed feed = e.Result;
            foreach (IssuesEntry issuesEntry in feed.Entries)
            {
                issueListBox.Items.Add(new ListableIssue(issuesEntry));
            }
            issueListBox.Refresh();
        }

        private void issueListBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            var issue = issueListBox.SelectedItem as ListableIssue;
            if (issue != null && issue.Issue.Content != null)
            {
                issueDetailTextBox.Text = issue.Issue.Content.Description;
            }
        }

        private void issueSummeryButton_Click(object sender, EventArgs e)
        {
            try
            {
                if (_service == null)
                {
                    _service = new ProjectHostingService(_projectName, _gUserId, _gPassword);
                    if (_proxy != null)
                        _service.ProxySettings = _proxy;
                }

                _service.GetAllIssuesSummeryCompleted += ServiceGetAllIssuesSummeryCompleted;
                _service.GetAllIssuesSummeryAsync(new object());
                ButtonEnableState(false);
                statusLabel.Text = "Fetching Summery ...";
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void ServiceGetAllIssuesSummeryCompleted(object sender, GetAllIssuesSummeryCompletedEventArgs e)
        {
            statusLabel.Text = "";
            ButtonEnableState(true);

            issueListBox.Items.Clear();
            IssuesFeed feed = e.IssuesFeed;
            foreach (IssuesEntry issuesEntry in feed.Entries)
            {
                issueListBox.Items.Add(new ListableIssue(issuesEntry));
            }
            issueListBox.Refresh();
        }

        private void issueCommentsButton_Click(object sender, EventArgs e)
        {
            if (issueListBox.SelectedItem != null)
            {
                try
                {
                    var issue = issueListBox.SelectedItem as ListableIssue;
                    if (issue != null)
                    {
                        int id = issue.Issue.Id;

                        if (_service == null)
                        {
                            _service = new ProjectHostingService(_projectName, _gUserId, _gPassword);
                            if (_proxy != null)
                                _service.ProxySettings = _proxy;
                        }

                        _service.GetAllIssueCommentsCompleted += ServiceGetAllIssueCommentsCompleted;
                        _service.GetAllIssueCommentsAsync(id.ToString(), new object());
                        ButtonEnableState(false);
                        statusLabel.Text = "Fetching Issue's Comments ...";
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }
            else
            {
                MessageBox.Show("Please select an Issue first.");
            }
        }

        private void ServiceGetAllIssueCommentsCompleted(object sender,
                                                         GetAllFeedCompletedEventArgs
                                                             <IssueCommentsFeed, IssueCommentsEntry> e)
        {
            statusLabel.Text = "";
            ButtonEnableState(true);

            IssueCommentsFeed feed = e.Result;
            issueDetailTextBox.Text = "";
            foreach (IssueCommentsEntry commentsEntry in feed.Entries)
            {
                if (commentsEntry.Content != null && commentsEntry.Content.Description != null)
                {
                    issueDetailTextBox.AppendText(commentsEntry.Content.Description);
                    issueDetailTextBox.AppendText("\n============================================\n");
                }
            }
            Refresh();
        }

        private void ButtonEnableState(bool state)
        {
            getIssueButton.Enabled = state;
            issueSummeryButton.Enabled = state;
            issueCommentsButton.Enabled = state;
        }

        private void submitButton_Click(object sender, EventArgs e)
        {
            if (MessageBox.Show("Are you sure about this submission?", "Confirmation", MessageBoxButtons.YesNo) ==
                DialogResult.Yes)
            {
                try
                {
                    var newEntry = new IssuesEntry
                                       {
                                           Author = new Author {Name = _gUserId},
                                           Title = titleTextBox.Text,
                                           Content = new Content {Description = newIssueTextBox.Text}
                                       };

                    if (_service == null)
                    {
                        _service = new ProjectHostingService(_projectName, _gUserId, _gPassword);
                        if (_proxy != null)
                            _service.ProxySettings = _proxy;
                    }

                    _service.SubmitNewIssueCompleted += ServiceSubmitNewIssueCompleted;
                    _service.SubmitNewIssueAsync(newEntry, "GoogleCodeIssueTrackerDemo-1.1", new object());
                    submitButton.Enabled = false;
                    statusLabel.Text = "Submitting new Issue ...";
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }
        }

        private void ServiceSubmitNewIssueCompleted(object sender,
                                                    SubmitNewEntryCompletedEventArgs<IssuesFeed, IssuesEntry> e)
        {
            if (e.Error != null)
            {
                MessageBox.Show("Submission failed.\nPlease check the settings and data.");
                submitButton.Enabled = true;
                statusLabel.Text = "";
                return;
            }
            submitButton.Enabled = true;
            statusLabel.Text = "New Issue Submitted Successfully with Id = " + e.Result.Id;
        }

        private void updateButton_Click(object sender, EventArgs e)
        {
            var worker = new BackgroundWorker();
            worker.DoWork += WorkerDoWork;
            worker.RunWorkerAsync();
        }

        private void WorkerDoWork(object sender, DoWorkEventArgs e)
        {
            WebRequest request = WebRequest.Create(UpdateUrl);
            if (_proxy != null)
                request.Proxy = _proxy;

            WebResponse response = request.GetResponse();

            var streamReader = new StreamReader(response.GetResponseStream());
            var sb = new List<string>();

            var readBuffer = new Char[256];
            int count = streamReader.Read(readBuffer, 0, 256);

            var str = new String(readBuffer, 0, count);
            sb.AddRange(str.Split(new[] {'\n', '\r'}));

            if (sb.Count == 3)
            {
                var currentVersion = new Version(OldVersion);
                var webVersion = new Version(sb[0]);

                if (webVersion.CompareTo(currentVersion) > 0)
                {
                    _updateAvailable = true;
                    _downloadString = sb[2];
                    _setupFileName = Path.GetFileName(sb[2]);
                    _newVersion = webVersion.ToString(4);
                }
            }
            streamReader.Close();
            response.Close();

            if (_updateAvailable)
            {
                if (MessageBox.Show("Current Issue Tracker Library Version : "
                                    + "\t" + OldVersion + "\n"
                                    + "New Issue Tracker Library Version : "
                                    + "\t" + _newVersion + "\n"
                                    + "\nUpdate With New Version Now?", "Issue Tracker Library Update Available",
                                    MessageBoxButtons.YesNo) == DialogResult.Yes)
                {
                    var client = new WebClient();
                    if (_proxy != null)
                        client.Proxy = _proxy;
                    client.DownloadFileCompleted += ClientDownloadFileCompleted;
                    Directory.CreateDirectory(Application.StartupPath + "\\Update\\");
                    string downloadPath = Application.StartupPath + "\\Update\\" + _setupFileName;
                    client.DownloadFileAsync(new Uri(_downloadString), downloadPath, downloadPath);
                }
            }
            else
            {
                MessageBox.Show("Sorry, no update is currently available.\nCheck again later.", "No Update");
            }
        }

        private static void ClientDownloadFileCompleted(object sender, AsyncCompletedEventArgs e)
        {
            var downloadPath = (e.UserState as string);
            Process.Start(Path.GetDirectoryName(downloadPath));
        }

        private void donateButton_Click(object sender, EventArgs e)
        {
            Process.Start("https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=1787302");
        }
    }

    internal class ListableIssue
    {
        internal ListableIssue(IssuesEntry entry)
        {
            Issue = entry;
        }

        internal IssuesEntry Issue { get; private set; }

        public override string ToString()
        {
            return Issue.Title;
        }
    }
}